/*
* Poppy Game Engine - https://pgetemplate.googlecode.com/svn/
* -----------------------------------------------------------------------
* Licensed under the BSD license, see LICENSE in PSPSDK root for details.
*
* Copyright (c) 2008 Poppy
*/

#include "stdafx.h"
#include "CRenderer.h"
#include "DriverInternal.h"
#include <stdio.h>

namespace PGERenderer
{

	void CRenderer::DrawPointList( FillablePoint* ppoint, DWORD count )
	{

		#ifdef WIN32

		VERTEX2D* p2D;
		m_pData->m_pMainVBuffer->Lock( m_pData->m_uVBOffset, count*sizeof(VERTEX2D), (void**)&p2D, 0 );
		for(unsigned int i = 0; i < count; ++i)
		{
			p2D[i].x = (float)ppoint[i].point.x;
			p2D[i].y = (float)ppoint[i].point.y;
			p2D[i].z = 0;
			p2D[i].rhw = 1.0f;
			p2D[i].color = ppoint[i].color;
		}
		m_pData->m_pMainVBuffer->Unlock();
		SetVertexType(VERTEX_TYPE_2D_COLOR, sizeof(VERTEX2D));
		m_pData->m_pD3DDevice->SetStreamSource( 0, m_pData->m_pMainVBuffer, m_pData->m_uVBOffset, m_pData->m_uVertexSize );
		m_pData->m_pD3DDevice->DrawPrimitive( (D3DPRIMITIVETYPE)PGE_POINTLIST, 0, count);
		m_pData->m_uVBOffset += count*sizeof(VERTEX2D);

		#endif

		#ifdef PSP

		VERTEX2D* p2D;
		p2D = (VERTEX2D*)GetMemory(count * sizeof(VERTEX2D));
		for(unsigned int i = 0; i < count; ++i)
		{
			p2D[i].color = ppoint[i].color;
			p2D[i].x = ppoint[i].point.x;
			p2D[i].y = ppoint[i].point.y;
			p2D[i].z = 0;
		}

		SetVertexType(VERTEX_TYPE_2D_COLOR, sizeof(VERTEX2D));
		DrawVertex(PGE_POINTLIST, count, p2D);
		CommandStall();

		#endif

	}

	void CRenderer::DrawLine( FillableLine& line )
	{

		#ifdef WIN32

		VERTEX2D* p2D;
		m_pData->m_pMainVBuffer->Lock( m_pData->m_uVBOffset, 2*sizeof(VERTEX2D), (void**)&p2D, 0 );
		p2D[0].x = (float)line.point1.x;
		p2D[0].y = (float)line.point1.y;
		p2D[0].z = 0;
		p2D[0].rhw = 1.0f;
		p2D[0].color = line.color;
		p2D[1].x = (float)line.point2.x;
		p2D[1].y = (float)line.point2.y;
		p2D[1].z = 0;
		p2D[1].rhw = 1.0f;
		p2D[1].color = line.color;
		SetVertexType(VERTEX_TYPE_2D_COLOR, sizeof(VERTEX2D));
		m_pData->m_pD3DDevice->SetStreamSource( 0, m_pData->m_pMainVBuffer, m_pData->m_uVBOffset, m_pData->m_uVertexSize );
		m_pData->m_pD3DDevice->DrawPrimitive( (D3DPRIMITIVETYPE)PGE_LINELIST, 0, 1);
		m_pData->m_uVBOffset += 2*sizeof(VERTEX2D);

		#endif

		#ifdef PSP

		VERTEX2D* p2D;
		p2D = (VERTEX2D*)GetMemory(2 * sizeof(VERTEX2D));
		p2D[0].color = line.color;
		p2D[0].x = line.point1.x;
		p2D[0].y = line.point1.y;
		p2D[0].z = 0;
		p2D[1].color = line.color;
		p2D[1].x = line.point2.x;
		p2D[1].y = line.point2.y;
		p2D[1].z = 0;

		SetVertexType(VERTEX_TYPE_2D_COLOR, sizeof(VERTEX2D));
		DrawVertex(PGE_LINELIST, 2, p2D);

		CommandStall();

		#endif

	}

	void CRenderer::DrawLineList( FillableLine* pline, DWORD count )
	{

		#ifdef WIN32

		for(unsigned int i = 0; i < count; ++i)
		{
			DrawLine( pline[i] );
		}

		#endif

		#ifdef PSP

		VERTEX2D* p2D;
		int vnumber = 2 * count;
		p2D = (VERTEX2D*)GetMemory(vnumber * sizeof(VERTEX2D));
		int offect(0);
		for(unsigned int i = 0; i < count; ++i)
		{
			p2D[offect].color = pline[i].color;
			p2D[offect].x = pline[i].point1.x;
			p2D[offect].y = pline[i].point1.y;
			p2D[offect].z = 0;

			++offect;

			p2D[offect].color = pline[i].color;
			p2D[offect].x = pline[i].point2.x;
			p2D[offect].y = pline[i].point2.y;
			p2D[offect].z = 0;

			++offect;
		}

		SetVertexType(VERTEX_TYPE_2D_COLOR, sizeof(VERTEX2D));
		DrawVertex(PGE_LINELIST, vnumber, p2D);

		CommandStall();

		#endif

	}

	void CRenderer::DrawLineStrip( PointList& points )
	{

		#ifdef WIN32
		
		VERTEX2D* p2D;
		m_pData->m_pMainVBuffer->Lock( m_pData->m_uVBOffset, points.count*sizeof(VERTEX2D), (void**)&p2D, 0 );
		for(unsigned int i = 0; i < points.count; ++i)
		{
			p2D[i].x = (float)points.ppoint[i].x;
			p2D[i].y = (float)points.ppoint[i].y;
			p2D[i].z = 0;
			p2D[i].rhw = 1.0f;
			p2D[i].color = points.color;
		}
		m_pData->m_pMainVBuffer->Unlock();
		SetVertexType(VERTEX_TYPE_2D_COLOR, sizeof(VERTEX2D));
		m_pData->m_pD3DDevice->SetStreamSource( 0, m_pData->m_pMainVBuffer, m_pData->m_uVBOffset, m_pData->m_uVertexSize );
		m_pData->m_pD3DDevice->DrawPrimitive( (D3DPRIMITIVETYPE)PGE_LINESTRIP, 0, points.count-1);
		m_pData->m_uVBOffset += points.count*sizeof(VERTEX2D);

		#endif

		#ifdef PSP
		
		VERTEX2D* p2D;
		p2D = (VERTEX2D*)GetMemory(points.count * sizeof(VERTEX2D));
		for(unsigned int i = 0; i < points.count; ++i)
		{
			p2D[i].color = points.color;
			p2D[i].x = points.ppoint[i].x;
			p2D[i].y = points.ppoint[i].y;
			p2D[i].z = 0;
		}

		SetVertexType(VERTEX_TYPE_2D_COLOR, sizeof(VERTEX2D));
		DrawVertex(PGE_LINESTRIP, points.count, p2D);
		CommandStall();

		#endif

	}

	void CRenderer::DrawPolygon( PointList& points )
	{

		#ifdef WIN32

		VERTEX2D* p2D;
		m_pData->m_pMainVBuffer->Lock( m_pData->m_uVBOffset, (points.count + 1)*sizeof(VERTEX2D), (void**)&p2D, 0 );
		unsigned int i(0);
		for(; i < points.count; ++i)
		{
			p2D[i].x = (float)points.ppoint[i].x;
			p2D[i].y = (float)points.ppoint[i].y;
			p2D[i].z = 0;
			p2D[i].rhw = 1.0f;
			p2D[i].color = points.color;
		}
		p2D[i].x = (float)points.ppoint[0].x;
		p2D[i].y = (float)points.ppoint[0].y;
		p2D[i].z = 0;
		p2D[i].rhw = 1.0f;
		p2D[i].color = points.color;

		m_pData->m_pMainVBuffer->Unlock();
		SetVertexType(VERTEX_TYPE_2D_COLOR, sizeof(VERTEX2D));
		m_pData->m_pD3DDevice->SetStreamSource( 0, m_pData->m_pMainVBuffer, m_pData->m_uVBOffset, m_pData->m_uVertexSize );
		m_pData->m_pD3DDevice->DrawPrimitive( (D3DPRIMITIVETYPE)PGE_LINESTRIP, 0, points.count);
		m_pData->m_uVBOffset += (points.count + 1)*sizeof(VERTEX2D);

		#endif

		#ifdef PSP

		VERTEX2D* p2D;
		p2D = (VERTEX2D*)GetMemory((points.count + 1) * sizeof(VERTEX2D));
		unsigned int i(0);
		for(; i < points.count; ++i)
		{
			p2D[i].color = points.color;
			p2D[i].x = points.ppoint[i].x;
			p2D[i].y = points.ppoint[i].y;
			p2D[i].z = 0;
		}
		p2D[i].color = points.color;
		p2D[i].x = points.ppoint[0].x;
		p2D[i].y = points.ppoint[0].y;
		p2D[i].z = 0;

		SetVertexType(VERTEX_TYPE_2D_COLOR, sizeof(VERTEX2D));
		DrawVertex(PGE_LINESTRIP, points.count + 1, p2D);
		CommandStall();

		#endif

	}

	void CRenderer::FillPolygon( PointList& points )
	{

		#ifdef WIN32

		VERTEX2D* p2D;
		m_pData->m_pMainVBuffer->Lock( m_pData->m_uVBOffset, points.count*sizeof(VERTEX2D), (void**)&p2D, 0 );
		for(unsigned int i = 0; i < points.count; ++i)
		{
			p2D[i].x = (float)points.ppoint[i].x;
			p2D[i].y = (float)points.ppoint[i].y;
			p2D[i].z = 0;
			p2D[i].rhw = 1.0f;
			p2D[i].color = points.color;
		}

		m_pData->m_pMainVBuffer->Unlock();
		SetVertexType(VERTEX_TYPE_2D_COLOR, sizeof(VERTEX2D));
		m_pData->m_pD3DDevice->SetStreamSource( 0, m_pData->m_pMainVBuffer, m_pData->m_uVBOffset, m_pData->m_uVertexSize );
		m_pData->m_pD3DDevice->DrawPrimitive( (D3DPRIMITIVETYPE)PGE_TRIANGLEFAN, 0, points.count - 2);
		m_pData->m_uVBOffset += points.count*sizeof(VERTEX2D);

		#endif

		#ifdef PSP

		VERTEX2D* p2D;
		p2D = (VERTEX2D*)GetMemory(points.count * sizeof(VERTEX2D));
		for(unsigned int i = 0; i < points.count; ++i)
		{
			p2D[i].color = points.color;
			p2D[i].x = points.ppoint[i].x;
			p2D[i].y = points.ppoint[i].y;
			p2D[i].z = 0;
		}

		SetVertexType(VERTEX_TYPE_2D_COLOR, sizeof(VERTEX2D));
		DrawVertex(PGE_TRIANGLEFAN, points.count, p2D);
		CommandStall();

		#endif

	}

	void CRenderer::DrawRect( PGEMath::SRECT_I& rect, DWORD color )
	{

		#ifdef WIN32
		
		VERTEX2D* p2D;

		m_pData->m_pMainVBuffer->Lock( m_pData->m_uVBOffset, 5*sizeof(VERTEX2D), (void**)&p2D, 0 );
		p2D[0].x = (float)rect.x;
		p2D[0].y = (float)rect.y;
		p2D[0].z = 0;
		p2D[0].rhw = 1.0f;
		p2D[0].color = color;
		p2D[1].x = (float)(rect.x + rect.w);
		p2D[1].y = (float)rect.y;
		p2D[1].z = 0;
		p2D[1].rhw = 1.0f;
		p2D[1].color = color;
		p2D[2].x = (float)(rect.x + rect.w);
		p2D[2].y = (float)(rect.y + rect.h);
		p2D[2].z = 0;
		p2D[2].rhw = 1.0f;
		p2D[2].color = color;
		p2D[3].x = (float)rect.x;
		p2D[3].y = (float)(rect.y + rect.h);
		p2D[3].z = 0;
		p2D[3].rhw = 1.0f;
		p2D[3].color = color;
		p2D[4].x = (float)rect.x;
		p2D[4].y = (float)rect.y;
		p2D[4].z = 0;
		p2D[4].rhw = 1.0f;
		p2D[4].color = color;
		m_pData->m_pMainVBuffer->Unlock();

		SetVertexType(VERTEX_TYPE_2D_COLOR, sizeof(VERTEX2D));
		m_pData->m_pD3DDevice->SetStreamSource( 0, m_pData->m_pMainVBuffer, m_pData->m_uVBOffset, m_pData->m_uVertexSize );
		m_pData->m_pD3DDevice->DrawPrimitive( (D3DPRIMITIVETYPE)PGE_LINESTRIP, 0, 4);
		m_pData->m_uVBOffset += 5*sizeof(VERTEX2D);
		#endif

		#ifdef PSP

		VERTEX2D* p2D;
		p2D = (VERTEX2D*)GetMemory(5 * sizeof(VERTEX2D));
		p2D[0].color = color;
		p2D[0].x = rect.x;
		p2D[0].y = rect.y;
		p2D[0].z = 0;
		p2D[1].color = color;
		p2D[1].x = rect.x + rect.w;
		p2D[1].y = rect.y;
		p2D[1].z = 0;
		p2D[2].color = color;
		p2D[2].x = rect.x + rect.w;
		p2D[2].y = rect.y + rect.h;
		p2D[2].z = 0;
		p2D[3].color = color;
		p2D[3].x = rect.x;
		p2D[3].y = rect.y + rect.h;
		p2D[3].z = 0;
		p2D[4].color = color;
		p2D[4].x = rect.x;
		p2D[4].y = rect.y;
		p2D[4].z = 0;

		SetVertexType(VERTEX_TYPE_2D_COLOR, sizeof(VERTEX2D));
		DrawVertex(PGE_LINESTRIP, 5, p2D);

		CommandStall();

		#endif

	}

	void CRenderer::DrawRectList( FillableRect* pRects, DWORD count )
	{

		#ifdef WIN32

		for(unsigned int i = 0; i < count; ++i)
		{
			DrawRect( pRects[i].rect, pRects[i].color );
		}

		#endif

		#ifdef PSP

		for(unsigned int i = 0; i < count; ++i)
		{
			VERTEX2D* p2D;
			p2D = (VERTEX2D*)GetMemory(5 * sizeof(VERTEX2D));
			p2D[0].color = pRects[i].color;
			p2D[0].x = pRects[i].rect.x;
			p2D[0].y = pRects[i].rect.y;
			p2D[0].z = 0;
			p2D[1].color = pRects[i].color;
			p2D[1].x = pRects[i].rect.x + pRects[i].rect.w;
			p2D[1].y = pRects[i].rect.y;
			p2D[1].z = 0;
			p2D[2].color = pRects[i].color;
			p2D[2].x = pRects[i].rect.x + pRects[i].rect.w;
			p2D[2].y = pRects[i].rect.y + pRects[i].rect.h;
			p2D[2].z = 0;
			p2D[3].color = pRects[i].color;
			p2D[3].x = pRects[i].rect.x;
			p2D[3].y = pRects[i].rect.y + pRects[i].rect.h;
			p2D[3].z = 0;
			p2D[4].color = pRects[i].color;
			p2D[4].x = pRects[i].rect.x;
			p2D[4].y = pRects[i].rect.y;
			p2D[4].z = 0;

			SetVertexType(VERTEX_TYPE_2D_COLOR, sizeof(VERTEX2D));
			DrawVertex(PGE_LINESTRIP, 5, p2D);
		}

		CommandStall();

		#endif

	}

	void CRenderer::FillRect( PGEMath::SRECT_I& rect, DWORD color )
	{

		#ifdef WIN32

		VERTEX2D* p2D;

		m_pData->m_pMainVBuffer->Lock( m_pData->m_uVBOffset, 4*sizeof(VERTEX2D), (void**)&p2D, 0 );
		p2D[0].x = (float)rect.x;
		p2D[0].y = (float)rect.y;
		p2D[0].z = 0;
		p2D[0].rhw = 1.0f;
		p2D[0].color = color;
		p2D[1].x = (float)(rect.x + rect.w);
		p2D[1].y = (float)rect.y;
		p2D[1].z = 0;
		p2D[1].rhw = 1.0f;
		p2D[1].color = color;
		p2D[2].x = (float)rect.x;
		p2D[2].y = (float)(rect.y + rect.h);
		p2D[2].z = 0;
		p2D[2].rhw = 1.0f;
		p2D[2].color = color;
		p2D[3].x = (float)(rect.x + rect.w);
		p2D[3].y = (float)(rect.y + rect.h);
		p2D[3].z = 0;
		p2D[3].rhw = 1.0f;
		p2D[3].color = color;
		m_pData->m_pMainVBuffer->Unlock();

		SetVertexType(VERTEX_TYPE_2D_COLOR, sizeof(VERTEX2D));
		
		m_pData->m_pD3DDevice->SetStreamSource( 0, m_pData->m_pMainVBuffer, m_pData->m_uVBOffset, m_pData->m_uVertexSize );
		m_pData->m_pD3DDevice->DrawPrimitive( (D3DPRIMITIVETYPE)PGE_TRIANGLESTRIP, 0, 2);
		m_pData->m_uVBOffset += 4*sizeof(VERTEX2D);

		#endif
		
		#ifdef PSP

		VERTEX2D* p2D;
		p2D = (VERTEX2D*)GetMemory(2 * sizeof(VERTEX2D));
		p2D[0].color = color;
		p2D[0].x = rect.x;
		p2D[0].y = rect.y;
		p2D[0].z = 0;

		p2D[1].color = color;
		p2D[1].x = rect.x + rect.w;
		p2D[1].y = rect.y + rect.h;
		p2D[1].z = 0;

		SetVertexType(VERTEX_TYPE_2D_COLOR, sizeof(VERTEX2D));
		DrawVertex(PGE_SPRITES, 2, p2D);

		CommandStall();

		#endif
	
	}

	void CRenderer::FillRectList( FillableRect* pRects, DWORD count )
	{

		#ifdef WIN32

		for(unsigned int i = 0; i < count; ++i)
		{
			FillRect( pRects[i].rect, pRects[i].color );
		}

		#endif

		#ifdef PSP

		VERTEX2D* p2D;
		int vnumber = 2 * count;
		p2D = (VERTEX2D*)GetMemory(vnumber * sizeof(VERTEX2D));
		int offect(0);
		for(unsigned int i = 0; i < count; ++i)
		{
			p2D[offect].color = pRects[i].color;
			p2D[offect].x = pRects[i].rect.x;
			p2D[offect].y = pRects[i].rect.y;
			p2D[offect].z = 0;

			++offect;

			p2D[offect].color = pRects[i].color;
			p2D[offect].x = pRects[i].rect.x + pRects[i].rect.w;
			p2D[offect].y = pRects[i].rect.y + pRects[i].rect.h;
			p2D[offect].z = 0;

			++offect;
		}

		SetVertexType(VERTEX_TYPE_2D_COLOR, sizeof(VERTEX2D));
		DrawVertex(PGE_SPRITES, vnumber, p2D);

		CommandStall();

		#endif

	}

	CRenderer* CRenderer::GetInstance()
	{
		return (CRenderer*)(CPSPDriver::GetInstance());
	}

	void CRenderer::Release()
	{
		CPSPDriver::Release();
	}

}
